﻿using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Red.Controls.Depot.FileViewItemsProviders;
using Red.Controls.ViewModels;
using Red.Core;
using Red.Core.Containers;
using Red.Core.Extensions;

namespace Red.Controls.Depot.ViewModels
{
    public class DepotTreeItemFavoriteRoot : DepotTreeItem
    {
        #region Data

        private SortedSet<string> _favorites = new SortedSet<string>();
        protected static readonly Canvas _favIcon;

        #endregion Data

        #region C-tor

        public DepotTreeItemFavoriteRoot( DepotTreeItem parent, DepotInfo depot )
            : base( "Favorites", "Drag & drop directory here to create a favorite", _favIcon, parent, depot )
        {
        }

        static DepotTreeItemFavoriteRoot()
        {
            _favIcon = (Canvas)Application.Current.FindResource( "appbar_star" );
        }
        
        #endregion C-tor

        #region Properties

        public override string BreadcrumbPath
        {
            get { return "{[fav]," + _depot.RootPath + ",icon:appbar_star}"; }
        }

        public IEnumerable<string> Favorites
        {
            get
            {
                return _favorites;
            }

            set
            {
                var newFavs = ( value == null ) ? new SortedSet<string>() : new SortedSet<string>( value );
                if ( newFavs != _favorites )
                {
                    _favorites = newFavs;
                    RebuildAsync().DoNotAwait();
                }
            }
        }

        #endregion Properties

        #region DepotTreeItem implementation

        public override FileViewItemsProvider GetItemsProvider()
        {
            return new EmptyItemsProvider();
        }

        public override bool AcceptsDraggedData( IDataObject obj )
        {
            return obj.GetDataPresent( "Red.DepotDirectory" );
        }

        public override async void DropDraggedData( IDataObject obj )
        {
            Debug.Assert( obj.GetDataPresent( "Red.DepotDirectory" ) );
            var path = obj.GetData( "Red.DepotDirectory" ) as string;
            Debug.Assert( path != null );
            _favorites.Add( path );

            await RebuildAsync();
            IsExpanded = true;
        }

        #endregion DepotTreeItem implementation

        #region LazyHierarchicalItem implementation

        protected override Task EnumerateChildrenAsync( IRangedCollection<DataItem> children )
        {
            children.Clear();

            // remove directory that no longer exists from the list of favorites
            _favorites.RemoveWhere( favPath => !Directory.Exists( favPath ) );

            foreach ( var favPath in _favorites )
            {
                if ( favPath.StartsWith( _depot.RootPath ) ) // note skip all favs not under the current root
                {
                    var title = favPath.Substring( _depot.RootPath.Length + 1 );
                    children.Add( new DepotTreeItemFavorite( title, this, favPath, _depot ) );
                }
            }

            return Task.CompletedTask;
        }

        #endregion LazyHierarchicalItem implementation
    }


    public class DepotTreeItemFavorite : DepotTreeItem
    {
        #region Data

        private readonly string _path;

        #endregion

        #region Properties

        public override string Path
        {
            get { return _path; }
        }

        public override string BreadcrumbPath
        {
            get { return _path.Replace( _depot.RootPath, "{[fav]," + _depot.RootPath + ",icon:appbar_star}" ); }
        }

        public override IEnumerable<RedMenuDataItem> Menu
        {
            get
            {
                return new List<RedMenuDataItem> { new RedMenuDataItem( new CommandWrapper( DepotBrowserCommands.RemoveFromFavorites, this ) ) };
            }
        }

        public override bool IsExpandable
        {
            get { return false; }
        }

        #endregion Properties

        #region C-tor

        public DepotTreeItemFavorite( string title, DepotTreeItem parent, string path, DepotInfo depot )
            : base( title, path, _folderIcon, parent, depot )
        {
            _path = path;
        }
        
        #endregion C-tor

        #region DepotTreeItem implementation

        public override FileViewItemsProvider GetItemsProvider()
        {
            return new DirectoryFileViewItemsProvider( _path, _depot, IsReadOnly );
        }

        #endregion DepotTreeItem implementation
    }
}